package com.wywah.core.filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Objects;

/**
 * 根据请求参数{query}中的m值的来动态设置lb
 * eg. /dynamic?m={serviceId}/xx/xx  -->  lb://serviceId
 * @see org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory
 * @see org.springframework.cloud.gateway.filter.factory.RemoveRequestParameterGatewayFilterFactory
 * @see org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory
 */
@Component
public class DynamicServerGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {
    @Override
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {
            ServerHttpRequest req = exchange.getRequest();
            String url= req.getQueryParams().getFirst("m");
            if(StringUtils.hasText(url)){
                url = url.startsWith("/") ? url.replaceFirst("/", "") : url;
            }
            Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
            if(Objects.isNull(route)){
                throw new RuntimeException("未找到路由信息");
            }
            String[] uris = url.split("/", 2);
            ServerWebExchangeUtils.addOriginalRequestUrl(exchange, req.getURI());
            // 构建新的路由信息
            Route newRoute = Route.async()
                    .asyncPredicate(route.getPredicate())
                    .filters(route.getFilters())
                    .id(route.getId())
                    .order(route.getOrder())
                    .uri(String.format("lb://%s", uris[0]))
                    .build();
            exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR,newRoute);
            // 路由重写
            ServerHttpRequest request = req.mutate().path("/"+uris[1]).build();
            exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, request.getURI());
            return chain.filter(exchange.mutate().request(request).build());
        };
    }
}
